#include <stdlib.h>
#include <iostream>
//#include <list>
#include <vector>
#include <cstdlib>
#include </home/daniel/workspace/DARP_Mestrado/src/location.h>
#include </home/daniel/workspace/DARP_Mestrado/src/rota.h>

#include <time.h>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <climits>
#include <string.h>
#include <math.h>
#include <algorithm>

/*namespace dislin {
 #include </home/daniel/dislin/dislin.h>

 }**/
using std::cout;
using std::cin;
using std::ios;
using std::cerr;
using std::endl;
using std::setprecision;
using std::ifstream;
using std::vector;
using std::min;
using std::max;
using std::srand;
//srand(time(NULL));


//Variaveis globais
vector<Location> vetorDosPontos;
//vector<Rota> solucao, s;
//vector<Rota> ::iterator IterRota;
//vector<Location>::iterator IterLocation;
vector<Location> vetorLocation;

struct Cabecalho {

	Cabecalho(int qntVeiculos, int qntReq, int tempMaxRota, int quat, int cinco) {
		this->qntVeiculos = qntVeiculos;
		this->qntReq = qntReq;
		this->quat = quat;
		this->cinco = cinco;
	}
	int qntVeiculos;
	int qntReq;
	int tempMaxRota;
	int quat;
	int cinco;
};

Cabecalho cabecalho(0, 0, 0, 0, 0);

double funcaoObjetivo, w0 = 1, w1 = 1, w2 = 1, w3 = 1, w4 = 1, b0 = 1, b1 = 1,
		b2 = 1, b3 = 1, b4 = 1;
int maxIter, maxIterILS, kpMax, delta;//, velocidadeMedia = 20;
int* id_Location, *acao_Location, garagemInicial, garagemFinal;
double* e_Location, *l_Location, *s_Location, *coordX, *coordY;
//double ** t ; //matriz, t;

//S√≥ as assinaturas dos m√©todos
void carregaDados();
void inicializaRotas(vector<Rota> &solucao);
//void solucaoInicial();
void solucaoInicial(vector<Rota> &solucao);
void heuristicaDeProgramacao(vector<Rota> &solucao);
//void calculaFuncaoObjetivo();
void ILS(vector<Rota> &solucao, int maxIter, int maxIterILS, int kpMax, int delta);
vector<Rota> MRD(vector<Rota> &sol, int num);
vector<Rota>& geraAleatoriamente(vector<Rota> &sol);
//vector<Rota>* perturbar(vector<Rota>* sol);
vector<Rota> pertubar(vector<Rota> &solucao);
//==== Estruturas de Vizinhaca  =====
//==== Estruturas de Vizinhaca  =====
//==== Estruturas de Vizinhaca  =====
vector<Rota>& reordenarRota(vector<Rota> solucao);
vector<Rota>& realocaPonto(vector<Rota> solucao);
vector<Rota>& trocaPontos(vector<Rota> solucao);
vector<Rota>& realocaBlocosEmbarque(vector<Rota> solucao);

bool verificaVagaDisponivel(vector<Rota>* sol);
bool verificaViabilidade(vector<Rota>* sol);
bool podeVisitar(int elemento);
void setRequisicoesVisitadas(int embarque);
Rota criaRotaDummy();

//void calculaVariaveis(vector<double> * A, vector<double> * B, vector<double> * D, vector<double> * W, vector<double> * R, vector<double> * Q,
//            vector<double> * e, vector<double> * s, vector<int> * acao, vector<int> elementosDaRota);
void calculaVariaveis(vector<double> &A, vector<double> &B, vector<double> &D,
		vector<double> &W, //vector<double> &R,
		vector<double> &Q,
		vector<double> &e, vector<double> &s, vector<int> &acao,
		vector<int> &elementosDaRota);

int indexOf(vector<int> , int);
//void calculaFO(vector<double> * F,vector<double> * l,vector<double> * R,vector<double> * B,vector<double> * W, vector<int> * elementosDaRota,
//        int * tempMaxCaronaCliente_R);
void calculaFO(vector<double> &F, vector<double> &l, vector<double> &R,
		vector<double> &B, vector<double> &W, vector<int> &elementosDaRota,
		int tempMaxCaronaCliente_R);
void calculaFi(vector<double> &F, vector<double> &l, vector<double> &R,
		vector<double> &B, vector<double> &W, vector<int> &elementosDaRota,
		int tempMaxCaronaCliente_R, int i);
double calculaSomatorioWp(double somaWp, vector<double> W, int i);
void atualizaVariaveis(vector<double> A, vector<double> B, vector<double> W,
		vector<double> D, vector<double> e, vector<double> s,
		vector<int> elementosDaRota, int i);
void calcularR(vector<double> B, vector<double> D, vector<double> R,
		vector<int> elementosDaRota);
void atualizaR(vector<double> B, vector<double> D, vector<double> R,
		vector<int> elementosDaRota, int j);
double calculaFuncaoObjetivo(vector<Rota> &solucao);
int retornaMenorDistancia(int elementoComparado);
void rotaToString(vector<Rota> &solucao);
int retornaIndice(vector<int> &rota, int elemento);
//vector<Rota> reordenarRota(vector<Rota> &solucaoMetodo);
//vector<Rota> realocaPonto(vector<Rota> &solucaoMetodo);
//vector<Rota> trocaPontos(vector<Rota> &solucaoMetodo);
//vector<Rota> realocaBlocosEmbarque(vector<Rota> &solucaoMetodo);
void vectorToString(vector<double> solucao);
//==================================
int numVeicLeitura, numPontosLeitura, capacidadeVeiculoLeitura;
double tempMaxRotaLeitura, tempMaxViagemLeitura;

int* idPontoLeitura; // ponto referente a garagem unica
int* infoPontoLeitura;
double* coordXLeitura;
double* coordYLeitura;
double* tempServPontoLeitura;
double* inicioJanelaLeitura;
double* fimJanelaLeitura;

double* tempMaxRotaVLeitura;
double* tempMaxEsperaVeiculoLeitura;
int* capacidadeDeCadaVeiculoLeitura;
int* garagemInicialLeitura;
int* garagemFinalLeitura;

int* cargaClienteLeitura;
double* tempMaxViagemClienteLeitura;
double ** distancias, **t;

bool* vetorControleVisita;
int W_TempoMaximo_Espera, //limiteDosEmbarques = (numPontosLeitura / 2),
tempMaxCaronaCliente_R, cargaMaximaDoVeiculo;

//==================================

/**
 * Metodo responsavel por inicializar as rotas
 */
void inicializaRotas(vector<Rota> & solucao) {
	//solucao(numVeicLeitura+1);
	cout << "===== Inicializa Rotas ==== Capacidade do Veiculos: "
			<< capacidadeVeiculoLeitura << endl;

	for (int i = 0; i < numVeicLeitura; i++) {
		vector<int> rt(capacidadeVeiculoLeitura, -1);
		vector<double> A(capacidadeVeiculoLeitura+2, 0.0), B(capacidadeVeiculoLeitura+2, 0.0),
				D(capacidadeVeiculoLeitura+2, 0.0), W(capacidadeVeiculoLeitura+2,
						0.0), R(capacidadeVeiculoLeitura+2, 0.0), T(
								capacidadeVeiculoLeitura+2, 0.0), Q(
										capacidadeVeiculoLeitura+2, 0.0), F(
												capacidadeVeiculoLeitura+2, 0.0);

		cout << "Cria objeto" << endl;
		Rota rota(rt, A, B, D, W, R, T, Q, F);
		cout << "Teste dentro do laco" << i << endl;
		//cout<< "Elemento A[2] da rota "<< rota.getA().at(0) <<endl;
		solucao.push_back(rota); //vector<Rota> solucao;
	}
	// cout << "Solucao ="<< solucao->size()<<endl;
	// cout << "Teste"<< endl;
	// cout << "Solucao ="<< solucao->at(0).getRota().at(0);//->at(0).getA().at(0) <<endl;
	//for(int j = 0; j < solucao->size(); ++j) {
	//    cout<< j << endl;
	//////   solucao->at(j)->getRota()->at(2);
	//////    solucao->at(j).getRota().at(1);
	//    cout<< "Solucao "<<solucao->at(j).getRota().at(1)<< endl;
	//}
	//    return solucao;
	cout << "Fim do Inicializa Rotas" << endl;
}

/**
 *
 *
 */
void solucaoInicial(vector<Rota> &solucao) {
	//inicializaRotas();
	cout << "Solucao Inicial Entrou no metodo" << endl;
	int qntInseridos = 0, cont = 0, cont1 = 0, indiceRandomico, nMax = 1000,
			adidiconarRequisicao, indiceDesembarque, ultimoElementoDaRota = 0,
			elementoEmbarque, elementoDesembarque;
	vector<int> rota;
	bool ehPossivelInserirNasRotas = true;
	bool* elementosComVagas = new bool[numVeicLeitura];
	for (int i = 0; i < numVeicLeitura; i++) {
		elementosComVagas[i] = true;
	}

	//     Instancia >> numVeicLeitura;
	//    Instancia >> numPontosLeitura;
	//    Instancia >> tempMaxRotaLeitura;
	//    Instancia >> capacidadeVeiculoLeitura;
	//    Instancia >> tempMaxViagemLeitura;

	while (ehPossivelInserirNasRotas) {

		indiceRandomico = rand() % numVeicLeitura;
		cout << "INDICE" << indiceRandomico << endl;
		rota = solucao.at(indiceRandomico).getRota();
		cout << "Rota " << indiceRandomico;
		for (int i = 0; i < rota.size(); i++) {
			cout << rota[i] << ", ";
		}

		adidiconarRequisicao = retornaMenorDistancia(ultimoElementoDaRota);
		cout << "=== Retorno da Requisicao do ultimoElemento "
				<< ultimoElementoDaRota << " " << adidiconarRequisicao << endl;
		if (adidiconarRequisicao == 999)
			break;

		cont = 0;

		for (int i = 0; i < (rota.size() / 2); i++) {
			if ((-1) == rota.at(i)) {
				rota[i] = (adidiconarRequisicao); //Embarque
				rota[i + (rota.size() / 2)] = (adidiconarRequisicao
						+ (numPontosLeitura / 2));
				elementoEmbarque = rota.at(i);
				for (int j = 1; j < (rota.size() / 2); j++) {
					//cout++;
					if (rota.at(j) == (elementoEmbarque
							+ (numPontosLeitura / 2))) {
						indiceDesembarque = cont; // Pega o indice do elemento de desembarque
					}
					//cont1++;
				}
				elementoDesembarque = rota.at(indiceDesembarque);
				// cout << ">>>Quantidade elementos inseridos >>" << qntInseridos << "<< elementosDisponiveis " << numPontosLeitura << endl;
				qntInseridos++;
				break;
			} else {
				if (cont == (rota.size() / 2 - 1)) {//Quando chego ao final da lista, ela esta completa
					elementosComVagas[indiceRandomico] = false; //Tiramos o elemento da lista
					//						System.out.println("Rota "+indiceRandomico+ "nao tem mais como inserir elementos na rota");
					//						System.out.println("Rota toString "+ rota.toString());
					cont = rota.size() / 2;
				}
			}//Fim ELSE
			cont++;
		}//Fim FOR

		solucao.at(indiceRandomico).setRota(rota);//<==== Ver aqui!
		//====
		if (elementosComVagas[indiceRandomico])
			setRequisicoesVisitadas(adidiconarRequisicao);
		//data.setRequisicoesVisitadas(adidiconarRequisicao, (adidiconarRequisicao - 1 + data.getId().length/2));
		cont = 0;
		for (int i = 0; i < numVeicLeitura; i++) {
			if (!elementosComVagas[i])
				cont++;
		}
		if (cont == numVeicLeitura)
			ehPossivelInserirNasRotas = false;
	}//Fim do WHILE

	cout << "FIM DO WHILE" << endl;
	//TODO FAZER PEGAR TODAS AS ROTAS

	cout << "Tamanho Solucao " << solucao.size() << endl;
	cout << "===>> Situacao do elemento visitado ou n" << endl;
	for (int i = 0; i < numPontosLeitura; i++) {
		cout << "Elemento (" << i << ")" << vetorControleVisita[i] << endl;

	}
	//TODO ALTERAR AQUI ROTA DUMMY ANULADA AQUIAQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI AQUI
	//	vector<int> rotaD;
	//	for (int i = 1; i < numPontosLeitura; i++) {
	//		if (vetorControleVisita[i]) {
	//			rotaD.push_back(i);
	//			cout << "Elemento adicionado na lista Dummy" << i << endl;
	//		}
	//	}
	//	int tamanhoDaRotaDummy = rotaD.size();
	//	vector<double> A, B, D, W, R, T, Q, F;
	//	for (int i = 0; i < rotaD.size(); i++) {
	//		A.push_back(0.0);
	//		B.push_back(0.0);
	//		D.push_back(0.0);
	//		W.push_back(0.0);
	//		R.push_back(0.0);
	//		T.push_back(0.0);
	//		Q.push_back(0.0);
	//		F.push_back(0.0);
	//	}
	//
	//	cout << "Cria objeto" << endl;
	//	Rota rotaDummy(rotaD, A, B, D, W, R, T, Q, F);
	//	cout << "Cria objeto ===> Qnt elementos Rota Dummy >>" << rotaD.size()<< endl;
	//
	//	//        vector<double> ADummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> BDummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> DDummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> WDummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> RDummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> TDummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> QDummy(tamanhoDaRotaDummy,0.0);
	//	//        vector<double> FDummy(tamanhoDaRotaDummy,0.0);
	//
	//	//      Rota rotaDummy(rotaD,
	//	//      vector<double> X(tamanhoDaRotaDummy,0.0),
	//	//      vector<double> BDummy,
	//	//      vector<double> DDummy,vector<double> WDummy,vector<double> RDummy,
	//	//      vector<double> TDummy,vector<double> QDummy,vector<double> FDummy);
	//
	//	//cout<< "Elemento A[2] da rota "<< rota.getA().at(0) <<endl;
	//	solucao.push_back(rotaDummy); //vector<Rota> solucao;
	//	cout << "Rota D adicionada [";
	//	for (int i = 0; i < rotaD.size(); i++) {
	//		cout << rotaDummy.getRota().at(i) << " ";
	//	}
	//	cout << "]" << endl;
	cout << "Solucao Com a Rota Dummy" << solucao.size() << endl;
	cout<< "Fim do Metodo SOLUCAO INICIAL"<<endl;
}

int retornaMenorDistancia(int elementoComparado) {
	double min = 99999999;
	cout << "Limite dos Embarques" << (numPontosLeitura / 2) << endl;
	if (elementoComparado < (numPontosLeitura / 2))
		for (int i = 0; i < (numPontosLeitura / 2); i++) {
			for (int j = 0; j < (numPontosLeitura / 2); j++) {
				if (i != elementoComparado)

					if (min > distancias[elementoComparado][i]
					                                        && podeVisitar(i)) {
						//  cout <<"=== Distancia "<<distancias[elementoComparado][i] << endl;
						elementoComparado = i;
						min = distancias[elementoComparado][i];
					}
			}
		}
	if (elementoComparado != 0) {
		if (elementoComparado == 99999999)
			return 0;
		return elementoComparado;
	}
	return 999;
}

bool podeVisitar(int elemento) {
	//  for(int i = 0; i < numPontosLeitura; i++){
	//cout <<"Elemento "<< elemento <<" Situacao " << vetorControleVisita[elemento] << endl;
	//}
	if (vetorControleVisita[elemento]) {
		// vetorControleVisita[elemento] = false;
		return true;
	} else
		return false;
}

void setRequisicoesVisitadas(int embarque) {
	vetorControleVisita[embarque] = false;
	vetorControleVisita[embarque + (numPontosLeitura / 2)] = false;
	//    cout<<"Vetor Controle Visita"<<endl;
	//    for (int i = 0; i < numPontosLeitura; i++) {
	//        cout<<vetorControleVisita[i]<< endl;
	//
	//
	//    }

}

Rota criaRotaDummy() {
	vector<int> rotaDummy;
	for (int i = 1; i < numPontosLeitura; i++) {
		if (podeVisitar(i))
			rotaDummy.push_back(i);
	}
	vector<double> A(rotaDummy.size()+2, 0), B(rotaDummy.size()+2, 0), D(
			rotaDummy.size()+2, 0), W(rotaDummy.size()+2, 0),
			R(rotaDummy.size()+2, 0), T(rotaDummy.size()+2, 0), Q(rotaDummy.size()+2,
					0), F(rotaDummy.size()+2, 0);
	Rota rota(rotaDummy, A, B, D, W, R, T, Q, F);
	return rota;
}

void heuristicaDeProgramacao(vector<Rota> &solucao) {
	cout << "Método Heurística de Programação" << endl;
	vector<double> A, B, D, R, W, T, Q, F, s, e, l;
	vector<int> elementosDaRota, acao;
	//Rota listaDeRotas;// = Rota( elementosDaRota, A, B, D, W, R, T, Q, F);
	cout<<"Quantidade de veiculos = "<< solucao.size()<< endl;
	rotaToString(solucao);
	for (int k = 0; k < solucao.size(); k++) {//Para cada rota calcularemos o atraso
		//listaDeRotas = solucao->at(k);
		A = solucao.at(k).getA();
		B = solucao.at(k).getB();
		D = solucao.at(k).getD();
		R = solucao.at(k).getR();
		W = solucao.at(k).getW();
		T = solucao.at(k).getT();
		Q = solucao.at(k).getQ();
		F = solucao.at(k).getF();

		elementosDaRota = solucao.at(k).getRota();
		int aux = 0;
		/*vetorLocation.at(i).setIdReq(idPontoLeitura[i]);
		 vetorLocation.at(i).setCoordX(coordXLeitura[i]);
		 vetorLocation.at(i).setCoordY(coordYLeitura[i]);
		 vetorLocation.at(i).setE(inicioJanelaLeitura[i]);
		 vetorLocation.at(i).setL(fimJanelaLeitura[i]);
		 vetorLocation.at(i).setS(tempServPontoLeitura[i]);
		 vetorLocation.at(i).setAcao(infoPontoLeitura[i]);
		 * */
		cout << "=====-----=====Tamanho da Rota k = "<<k<<" >>" << elementosDaRota.size()<< endl;
		for (int i = 0; i < elementosDaRota.size(); i++) {
			aux = elementosDaRota.at(i);//Retorna o id
			e.push_back(vetorLocation.at(aux).getE());
			cout<<"===== E ===== 0 = "<<e[i]<<endl;

			l.push_back(vetorLocation.at(aux).getL());
			s.push_back(vetorLocation.at(aux).getS());
			acao.push_back(vetorLocation.at(aux).getAcao());
		}//Fim - acaba aqui de carregar as info de cada rota

		cout<<"===== TAMANHO DE E =====  = "<<e.size()<<endl;
		//Inicializa Vari√°veis
		W[0] = 0;
		A[0] = 0;
		Q[0] = 0;
		D.at(0) = B.at(0) = e[0];
		cout<<"///\\\>>>>><<<<<>>>>>> B INICIAL = "<<B[0]<<">>>>><<<<<>>>>>> D INICIAL = "<<D[0]<<">>>>><<<<<>>>>>> E INICIAL = "<<e[0]<<endl;
		//		D[0] = 0;

		//calculaVariaveis(A, B, D, W, R, Q, e, s, acao, elementosDaRota);//     OK OK OK OK OK OK
		calculaVariaveis(A, B, D, W, Q, e, s, acao, elementosDaRota);//     OK OK OK OK OK OK

		//		cout<<"Apos o calculaVeriaveis D 0= "<< D[0]<<endl;
		//		cout<<"Apos o calculaVeriaveis D 1= "<< D[1]<<endl;
		calculaFO(F, l, R, B, W, elementosDaRota, tempMaxCaronaCliente_R);//TODO  <<<< ----- ====== ------ ====

		double somaWp = 0;
		somaWp = calculaSomatorioWp(somaWp, W, 1);
		B[0] = (e.at(0) + min(F.at(0), somaWp));
		cout<<endl;
		cout<<">>>>>+++++<<<<<<<+++++>>>>>>>>>>  Somatorio Meio === "<<somaWp<<" F 0 = "<<F.at(0)<<endl;

		atualizaVariaveis(A, B, W, D, e, s, elementosDaRota, 0);//<=======================================

		calcularR(B, D, R, elementosDaRota);//Calcular somente os pontos de embarque

		for (int i = 1; i < elementosDaRota.size(); i++) {//Calcular vo != v1 SOMENTE PARA OS PONTOS DE EMBARQUE

			if (elementosDaRota.at(i) < (numPontosLeitura / 2)){
				calculaFi(F, l, R, B, W, elementosDaRota, tempMaxCaronaCliente_R, i);//TODO  <<<< ----- ====== ------ ====
				somaWp = calculaSomatorioWp(somaWp, W, i);
				if (elementosDaRota.at(i) != 0) {
					B[i] = (B.at(i) + min(F.at(i), somaWp));
					D[i] = (B.at(i) + s.at(i));
					W[i] = (B.at(i) - A.at(i));
					atualizaVariaveis(A, B, W, D, e, s, elementosDaRota, i);//<----
					atualizaR(B, D, R, elementosDaRota, i);
				}
			}
		}//Fim FOR

		for (int i = 0; i < A.size(); i++) {
			cout << "A[" << i << "]" << k << " = " << A[i] << endl;
			cout << "B[" << i << "]" << k << " = " << B[i] << endl;
			cout << "D[" << i << "]" << k << " = " << D[i] << endl;
			cout << "W[" << i << "]" << k << " = " << W[i] << endl;
			cout << "R[" << i << "]" << k << " = " << R[i] << endl;
			cout << "F[" << i << "]" << k << " = " << F[i] << endl;

		}
		solucao.at(k).setVectorA(A);
		solucao.at(k).setVectorB(B);
		solucao.at(k).setVectorD(D);
		solucao.at(k).setVectorR(R);
		solucao.at(k).setVectorW(W);
		solucao.at(k).setVectorT(T);
		solucao.at(k).setVectorQ(Q);
		solucao.at(k).setVectorF(F);
	}//Fim FOR

}//Fim Metodo Heuristica Programacao

//atualizaVariaveis(A, B, W, D, e, s, elementosDaRota);
void atualizaVariaveis(vector<double> A, vector<double> B, vector<double> W,
		vector<double> D, vector<double> e, vector<double> s,
		vector<int> elementosDaRota, int numeroI) {
	//	cout << "Método Atualiza Variáveis " << endl;
	//	int i = 0;
	//	//for (vector<int> ::iterator it = elementosDaRota.begin(); it!= elementosDaRota.end(); it++) {//P e U
	//	for (int i = 1; i < elementosDaRota.size(); i++) {
	////		A[i] = (D.at(i - 1) + t[i - 1][i]);//Para P U G+
	////		B[i] = max(e[i], A.at(i));//Para P U G+
	//		A[i] = D[i] - W[i];
	//		B[i] = B[i]+s[i]+ t[elementosDaRota[i-1]][elementosDaRota[i]]+ W[i];
	//		//if (A.size() != i) {
	//			D[i] = (B.at(i) + s[i]); //Para P e U
	//		//} else {
	//		//	D[i] = (B.at(i));//Para G+
	//		//}
	//		W[i] = (B.at(i) - A.at(i)); // Para P U G+
	//		//i++;
	//	}

	cout << "====== Inicio do Método Atualiza Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Atualiza Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Atualiza Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Atualiza Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Atualiza Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Atualiza Variáveis ====== " << elementosDaRota.size() << endl;

//	//Inicia a Garagem G-
//	B[0] = e_Location[0];//e_Location[0]
//	D[0] = B[0];
//	A[0] = W[0] = 0;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento G- "<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[0]<<" Elemento G- i = "<< 0<<endl;
	//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< [i+1]<<" i = "<< i+1<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[0]<<" Elemento G- i = "<< 0<<endl;
	//cout<< "Antes do for Q ["<< 0<< "] = "<<Q[0]<< endl;

	//G- ---> primeira REQUISICAO
	cout<<"elementosDaRota[0] = "<<elementosDaRota[0]<< "e_Location[elementosDaRota[0]] = "<<e_Location[elementosDaRota[0]]<<" e A[elementosDaRota[0]] = "<< A[elementosDaRota[0]]<< endl;
	B[1] = max(e_Location[elementosDaRota[0]], A[elementosDaRota[0]]);
	D[1] = B[1] + s_Location[elementosDaRota[0]];
	A[1] = D[0] +  t[0][elementosDaRota[0]];
	W[1] = B[1] - A[1];

	int i = 0;

	//Requisicoes P e U
	for (i = numeroI; i < elementosDaRota.size(); i++) {

		//i+1 para os vetores das variaveis pois G- comecou com 0
		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[i]<<" i = "<< i+1<<endl;
		//B[i+1] = B[i]+ s_Location[elementosDaRota[i]]+ t[elementosDaRota[i-1]][elementosDaRota[i]]+ W[i+1];//ASSIM COMO A MODELAGEM MAURI
		B[i+1] = max(e_Location[elementosDaRota[i]], A[i+1]);
		D[i+1] = B[i+1] + s_Location[elementosDaRota[i]]; //Para P e U
		//A[i+1] = B[i+1] - W[i+1];// COMO A MODELAGEM DO MAURI
		A[i+1] = D[i] + t[elementosDaRota[i-1]][elementosDaRota[i]];
		W[i+1] = B[i+1] - A[i+1]; //Para P U G+
	}
//=======================================

	//De Acordo com a definicao do DARP
	B[i+1] = max(e_Location[elementosDaRota[i-1]], A[i+1]);
	D[i+1] = 0; //Para G+
	A[i+1] = D[i] + t[elementosDaRota[i-1]][numPontosLeitura];//P u U u G+
	W[i+1] = B[i+1] - A[i+1]; //Para P u U u G+

//=======================================
	for (int l = 0; l < A.size(); ++l) {
		cout<< "Elemento i = "<< l<< endl;
		cout<< "B ["<<i+1<<"]"<< B[i+1]<<endl;
		cout<< "D ["<<i+1<<"]"<< D[i+1]<<endl;
		cout<< "A ["<<i+1<<"]"<< A[i+1]<<endl;
		cout<< "W ["<<i+1<<"]"<< W[i+1]<<endl;
	}


	for (int j = 0; j <= 49; ++j) {
		cout<<" aqui "<< endl;
		cout<< "Slocaciont ["<< j<< "] "<<tempServPontoLeitura[j]<< " acao = "<< acao_Location[j]<<endl;
	}
	cout<< "A ====>>>"<< A.size()<<endl;
	cout<< "B ====>>>"<< B.size()<<endl;
	cout<< "D ====>>>"<< D.size()<<endl;
	//cout<< "R ====>>>"<< R.size()<<endl;
	cout<< "W ====>>>"<< W.size()<<endl;
//====>>> ANTES DE MODIFICAR O CALCULO DAS VARIAVEIS <<<====
//
//
//	//Inicia a Garagem G-
//	B[0] = e_Location[0];//e_Location[0]
//	D[0] = B[0];
//	A[0] = W[0] = 0;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento G- "<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[0]<<" Elemento G- i = "<< 0<<endl;
//
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[0]<<" Elemento G- i = "<< 0<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[0]<<" Elemento G- i = "<< 0<<endl;
//	//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< [i+1]<<" i = "<< i+1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[0]<<" Elemento G- i = "<< 0<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[0]<<" Elemento G- i = "<< 0<<endl;
//	//cout<< "Antes do for Q ["<< 0<< "] = "<<Q[0]<< endl;
//
//	//G- ---> primeira REQUISICAO
//	B[1] = B[0] + s_Location[elementosDaRota[0]]+ t[0][elementosDaRota[1]]+ W[0];
//	D[1] = B[1] + s_Location[elementosDaRota[0]];
//	A[1] = D[1] - W[1];
//	W[1] = B[1] - A[1];
//
//	//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  ACAO i= "<< acao[0]<< " Q = "<<Q[1]<<" i = "<< i+1<<endl;
//
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[0]<<" i = "<< 0<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[1]<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B alt i= "<< max(e[1],A[1])<<" i = "<< 1<<endl;
//
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[1]<<" i = "<< 1<<endl;
//	int Aalt = D[0] + t[0][1], Balt1=  max(e[1],A[1]), Balt2 =max(e[1],D[0] + t[0][1]);
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A alt i= "<< Aalt<<" i = "<< 1<<endl;
//
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B alt i= "<< Balt1<<" ou com a alt alt"<<Balt2<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[1]<<" i = "<< 1<<endl;
//	//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< R[i+1]<<" i = "<< i+1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[1]<<" ou "<< Balt1 - Aalt<<" ou ainda "<<Balt2 - Aalt<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[1]<<" i = "<< 1<<endl;
//	//cout<< "Antes do for Q ["<< 1<< "] = "<<Q[0] + acao_Location[0]<< endl;
//
//	int i = 0;
//
//	//Requisicoes P e U
//	for (i = 1; i < elementosDaRota.size(); i++) {
//		//Aalt = D[i] + t[i][i+1]; Balt1=  max(e[i+1],A[i+1]); Balt2 =max(e[i+1],D[i] + t[i][i+1]);
//		//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  ACAO i= "<< acao[i-1]<<" i = "<< i-1<<endl;
//		//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  ACAO i= "<< acao[i-1]<< " Q = "<<Q[i]<<" i = "<< i<<endl;
//		cout<<">>>>>>>>>> ------------ Aqui "<< i <<endl;
//		//i+1 para os vetores das variaveis pois G- comecou com 0
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[i]<<" i = "<< i+1<<endl;
//		B[i+1] = B[i]+ s_Location[elementosDaRota[i]]+ t[elementosDaRota[i-1]][elementosDaRota[i]]+ W[i+1];
//
//		D[i+1] = B[i+1] + s_Location[elementosDaRota[i]]; //Para P e U
//
//
//		A[i+1] = B[i+1] - W[i+1];
//		W[i+1] = B[i+1] - A[i+1]; //Para P U G+
//
//
//		//		B[i] = B[i-1]+ s_Location[elementosDaRota[i]]+ t[elementosDaRota[i-1]][elementosDaRota[i]]+ W[i];
//		//		D[i] = B[i] + s_Location[elementosDaRota[i]]; //Para P e U
//		//		Q[i] = Q[i-1] + acao[i];
//		//		A[i] = D[i] - W[i];
//		//		W[i] = B[i] - A[i]; //Para P U G+
//
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[i]<< " local rota = "<< i<<" das variaveis i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[i+1]<< Balt1<<" ou com a alt alt"<<Balt2<<" i = "<< i+1<<endl;
//
//
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[i+1]<<" ou a alt "<< Aalt<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[i+1]<<" i = "<< i+1<<endl;
//		//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< R[i+1]<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[i+1]<<" ou "<< Balt1 - Aalt<<" ou ainda "<<Balt2 - Aalt<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[i+1]<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< acao_Location[i+1]<<" i = "<< i+1<<endl;
//		cout<< "B ["<<i+1<<"]"<< B[i+1]<<endl;
//		cout<< "D ["<<i+1<<"]"<< D[i+1]<<endl;
//
//		cout<< "A ["<<i+1<<"]"<< A[i+1]<<endl;
//		cout<< "W ["<<i+1<<"]"<< W[i+1]<<endl;
//		//cout << ">>>>>>>>>>>>>>>>> Loop"<<endl;
//		//  i++;
//
//	}
//	//cout<< " Q ["<< i+1<< "] = "<<Q[i] + acao_Location[i]<< "  Q "<< Q[i+1]<< endl;
//	//	cout << ">>>>>>>>>>>>>>>>> Loop ===== Variaveis i = "<< i+1<<" "<<i+2<< "acao 49 = "<<acao_Location[49] <<endl;
//
//	//Finaliza a Garagem G+
//	//cout<<"Elemenot = "<<elementosDaRota[i] << " Slocation do elem ant "<<s_Location[elementosDaRota[i]]<< " Slocation do elem ant "<<s_Location[27]<<endl;
//	//cout<<"Num pontos leitura = "<< numPontosLeitura<< "Slocation"<<elementosDaRota[i]<<endl;
//
//	//	D[i+2] = B[i+2] + s_Location[numPontosLeitura];//Para G+ indice 49
//	//	cout<< "D ["<<i+2<<"]"<< D[i+2]<<endl;
//	//Q[i+2] = Q[i+1] + acao[49];
//	//cout<< "Q ["<<i+2<<"]"<< Q[i+2]<<endl;
//	//cout<< "Q "<< i+2<<" "<< Q[i+2]<<" q i+1 "<< Q[i+1]<<" Acao 49 "<< acao[49]<<endl;
//	cout << ">>>>>>>>>>>>>>>>> FIM DO LOOP ==================== I = "<<i<<" i+1 = "<<i+1<<endl;
//	cout<<"B ["<< i+1<< "] "<<B[i+1]<<endl;
//	cout<<"Elemento rota = "<<elementosDaRota[i-1]<< endl;
//	cout<<"S ["<< i+1<< "] "<<s_Location[elementosDaRota[i-1]]<<endl;
//
//	B[i+1] = B[i]+ s_Location[elementosDaRota[i-1]]+ t[elementosDaRota[i-1]][numPontosLeitura]+ W[i+1];
//	cout<<"B ["<< i+1<< "] "<<B[i+1]<<endl;
//	D[i+1] = B[i+1] + s_Location[numPontosLeitura]; //Para P e U
//
//	A[i+1] = B[i+1] - W[i+1];
//	W[i+1] = B[i+1] - A[i+1]; //Para P U G+
//	cout<< "B ["<<i+1<<"]"<< B[i+1]<<endl;
//	cout<< "D ["<<i+1<<"]"<< D[i+1]<<endl;
//
//	cout<< "A ["<<i+1<<"]"<< A[i+1]<<endl;
//	cout<< "W ["<<i+1<<"]"<< W[i+1]<<endl;

}

void calculaVariaveis(vector<double> &A, vector<double> &B, vector<double> &D,
		vector<double> &W, //vector<double> &R,
		vector<double> &Q,
		vector<double> &e, vector<double> &s, vector<int> &acao,
		vector<int> &elementosDaRota) {

	cout << "====== Inicio do Método Calcula Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Calcula Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Calcula Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Calcula Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Calcula Variáveis ====== " << elementosDaRota.size() << endl;
	cout << "====== Inicio do Método Calcula Variáveis ====== " << elementosDaRota.size() << endl;


	//Inicia a Garagem G-
	B[0] = e_Location[0];//e_Location[0]
	D[0] = B[0];
	A[0] = W[0] = Q[0] = 0;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento G- "<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Q i= "<< Q[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[0]<<" Elemento G- i = "<< 0<<endl;
	//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< [i+1]<<" i = "<< i+1<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[0]<<" Elemento G- i = "<< 0<<endl;
	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[0]<<" Elemento G- i = "<< 0<<endl;
	//cout<< "Antes do for Q ["<< 0<< "] = "<<Q[0]<< endl;

	//G- ---> primeira REQUISICAO
	cout<<"elementosDaRota[0] = "<<elementosDaRota[0]<< "e_Location[elementosDaRota[0]] = "<<e_Location[elementosDaRota[0]]<<" e A[elementosDaRota[0]] = "<< A[elementosDaRota[0]]<< endl;
	B[1] = max(e_Location[elementosDaRota[0]], A[elementosDaRota[0]]);
	//B[1] = B[0] + s_Location[elementosDaRota[0]]+ t[0][elementosDaRota[0]]+ W[0];// DE ACORDO COM A MODELAGEM DO MAURI
	D[1] = B[1] + s_Location[elementosDaRota[0]];
	A[1] = D[0] +  t[0][elementosDaRota[0]];
	//A[1] = D[1] - W[1];// DE ACORDO COM A MODELAGEM DO MAURI
	W[1] = B[1] - A[1];
	Q[1] = Q[0] + acao_Location[elementosDaRota[0]];//
	//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  ACAO i= "<< acao[0]<< " Q = "<<Q[1]<<" i = "<< i+1<<endl;

//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[0]<<" i = "<< 0<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[1]<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B alt i= "<< max(e[1],A[1])<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Q i= "<< Q[1]<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[1]<<" i = "<< 1<<endl;
//	int Aalt = D[0] + t[0][1], Balt1=  max(e[1],A[1]), Balt2 =max(e[1],D[0] + t[0][1]);
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A alt i= "<< Aalt<<" i = "<< 1<<endl;
//
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B alt i= "<< Balt1<<" ou com a alt alt"<<Balt2<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[1]<<" i = "<< 1<<endl;
//	//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< R[i+1]<<" i = "<< i+1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[1]<<" ou "<< Balt1 - Aalt<<" ou ainda "<<Balt2 - Aalt<<" i = "<< 1<<endl;
//	cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[1]<<" i = "<< 1<<endl;
//	//cout<< "Antes do for Q ["<< 1<< "] = "<<Q[0] + acao_Location[0]<< endl;

	int i = 0;

	//Requisicoes P e U
	for (i = 1; i < elementosDaRota.size(); i++) {
		//Aalt = D[i] + t[i][i+1]; Balt1=  max(e[i+1],A[i+1]); Balt2 =max(e[i+1],D[i] + t[i][i+1]);
		//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  ACAO i= "<< acao[i-1]<<" i = "<< i-1<<endl;
		//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  ACAO i= "<< acao[i-1]<< " Q = "<<Q[i]<<" i = "<< i<<endl;
		cout<<">>>>>>>>>> ------------ Aqui "<< i <<endl;
		//i+1 para os vetores das variaveis pois G- comecou com 0
		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[i]<<" i = "<< i+1<<endl;
		//B[i+1] = B[i]+ s_Location[elementosDaRota[i]]+ t[elementosDaRota[i-1]][elementosDaRota[i]]+ W[i+1];//ASSIM COMO A MODELAGEM MAURI
		B[i+1] = max(e_Location[elementosDaRota[i]], A[i+1]);
		D[i+1] = B[i+1] + s_Location[elementosDaRota[i]]; //Para P e U
		//A[i+1] = B[i+1] - W[i+1];// COMO A MODELAGEM DO MAURI
		A[i+1] = D[i] + t[elementosDaRota[i-1]][elementosDaRota[i]];
		W[i+1] = B[i+1] - A[i+1]; //Para P U G+

		Q[i+1] = Q[i] + acao_Location[elementosDaRota[i]];

		//		B[i] = B[i-1]+ s_Location[elementosDaRota[i]]+ t[elementosDaRota[i-1]][elementosDaRota[i]]+ W[i];
		//		D[i] = B[i] + s_Location[elementosDaRota[i]]; //Para P e U
		//		Q[i] = Q[i-1] + acao[i];
		//		A[i] = D[i] - W[i];
		//		W[i] = B[i] - A[i]; //Para P U G+

//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Elemento da rota i= "<< elementosDaRota[i]<< " local rota = "<< i<<" das variaveis i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  B i= "<< B[i+1]<< Balt1<<" ou com a alt alt"<<Balt2<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  Q i= "<< Q[i+1]<<" i = "<< i+1<<endl;
//		cout<< " Q ["<< i+1<< "] = "<<Q[i] + acao_Location[elementosDaRota[i]]<< endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  A i= "<< A[i+1]<<" ou a alt "<< Aalt<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  D i= "<< D[i+1]<<" i = "<< i+1<<endl;
//		//cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  R i= "<< R[i+1]<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  W i= "<< W[i+1]<<" ou "<< Balt1 - Aalt<<" ou ainda "<<Balt2 - Aalt<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< s_Location[i+1]<<" i = "<< i+1<<endl;
//		cout<<">>>>>>>>>>>>>>>>>>>>>> ===============  S i= "<< acao_Location[i+1]<<" i = "<< i+1<<endl;
//		cout<< "B ["<<i+1<<"]"<< B[i+1]<<endl;
//		cout<< "D ["<<i+1<<"]"<< D[i+1]<<endl;
//		cout<< "Q ["<<i+1<<"]"<< Q[i+1]<<endl;
//		cout<< "A ["<<i+1<<"]"<< A[i+1]<<endl;
//		cout<< "W ["<<i+1<<"]"<< W[i+1]<<endl;
//		//cout << ">>>>>>>>>>>>>>>>> Loop"<<endl;
//		//  i++;

	}
	//cout<< " Q ["<< i+1<< "] = "<<Q[i] + acao_Location[i]<< "  Q "<< Q[i+1]<< endl;
	//	cout << ">>>>>>>>>>>>>>>>> Loop ===== Variaveis i = "<< i+1<<" "<<i+2<< "acao 49 = "<<acao_Location[49] <<endl;

	//Finaliza a Garagem G+
	//cout<<"Elemenot = "<<elementosDaRota[i] << " Slocation do elem ant "<<s_Location[elementosDaRota[i]]<< " Slocation do elem ant "<<s_Location[27]<<endl;
	//cout<<"Num pontos leitura = "<< numPontosLeitura<< "Slocation"<<elementosDaRota[i]<<endl;

	//D[i+2] = B[i+2] + s_Location[numPontosLeitura];//Para G+ indice 49
	//cout<< "D ["<<i+2<<"]"<< D[i+2]<<endl;
	//Q[i+2] = Q[i+1] + acao[49];
	//cout<< "Q ["<<i+2<<"]"<< Q[i+2]<<endl;
	//cout<< "Q "<< i+2<<" "<< Q[i+2]<<" q i+1 "<< Q[i+1]<<" Acao 49 "<< acao[49]<<endl;
	cout << ">>>>>>>>>>>>>>>>> FIM DO LOOP ==================== I = "<<i<<" i+1 = "<<i+1<<endl;
	//cout<<"B ["<< i+1<< "] "<<B[i+1]<<endl;
	//cout<<"Elemento rota = "<<elementosDaRota[i-1]<< endl;
	//cout<<"S ["<< i+1<< "] "<<s_Location[elementosDaRota[i-1]]<<endl;
//=======================================

	//De Acordo com a definicao do DARP
	B[i+1] = max(e_Location[elementosDaRota[i-1]], A[i+1]);
	D[i+1] = 0; //Para G+
	A[i+1] = D[i] + t[elementosDaRota[i-1]][numPontosLeitura];//P u U u G+
	W[i+1] = B[i+1] - A[i+1]; //Para P u U u G+

	Q[i+1] = Q[i] + acao_Location[numPontosLeitura];

//=======================================

//	B[i+1] = B[i]+ s_Location[elementosDaRota[i-1]]+ t[elementosDaRota[i-1]][numPontosLeitura]+ W[i+1];
	//cout<<"B ["<< i+1<< "] "<<B[i+1]<<endl;
	//D[i+1] = B[i+1] + s_Location[numPontosLeitura]; //Para P e U
//	Q[i+1] = Q[i] + acao[numPontosLeitura];
//	A[i+1] = B[i+1] - W[i+1];
//	W[i+1] = B[i+1] - A[i+1]; //Para P U G+
	for (int l = 0; l < A.size(); ++l) {
		cout<< "Elemento i = "<< l<< endl;
		cout<< "B ["<<i+1<<"]"<< B[i+1]<<endl;
		cout<< "D ["<<i+1<<"]"<< D[i+1]<<endl;
		cout<< "Q ["<<i+1<<"]"<< Q[i+1]<<endl;
		cout<< "A ["<<i+1<<"]"<< A[i+1]<<endl;
		cout<< "W ["<<i+1<<"]"<< W[i+1]<<endl;
	}


	for (int j = 0; j <= 49; ++j) {
		cout<<" aqui "<< endl;
		cout<< "Slocaciont ["<< j<< "] "<<tempServPontoLeitura[j]<< " acao = "<< acao_Location[j]<<endl;
	}
	cout<< "A ====>>>"<< A.size()<<endl;
	cout<< "B ====>>>"<< B.size()<<endl;
	cout<< "D ====>>>"<< D.size()<<endl;
	//cout<< "R ====>>>"<< R.size()<<endl;
	cout<< "W ====>>>"<< W.size()<<endl;
}// FIM DO METODO calculaVariaveis


void calculaFO(vector<double> &F, vector<double> &l, vector<double> &R,
		vector<double> &B, vector<double> &W, vector<int> &elementosDaRota,
		int tempMaxCaronaCliente_R) {

	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout << "//////////----------------------Método Calcula FO "<<W.size()<<" ------------------------\\\\\\\\\\\ " << endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;

	double minimo = 9999, somatorio, maxMin = 0;

	for (int j = 0; j < B.size(); ++j) {
		cout<<" MINIMO F "<<j<< " eh = " <<minimo<<endl;
		somatorio = 0;

		for (int p = 1; p < j; ++p) {
			cout<<" Somatorio de W["<<p<< "] = "<<W[p]<<" eh = " <<somatorio<<endl;
			somatorio += W[p];
		}

		maxMin = l[j] - B[j];

		if(minimo > (somatorio + maxMin)){
			minimo = (somatorio + maxMin);
		}
	}

	cout<<"-----------------/////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\-----------------------"<<endl;

}



void calculaFi(vector<double> &F, vector<double> &l, vector<double> &R,
		vector<double> &B, vector<double> &W, vector<int> &elementosDaRota,
		int tempMaxCaronaCliente_R, int i) {
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout << "//////////----------------------Método Calcula FO "<<W.size()<<" ------------------------\\\\\\\\\\\ " << endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;
	cout<< "------------------------------------------------------------------------------------------"<<endl;

	double minimo = 9999, somatorio, maxMin = 0;
if(i < numPontosLeitura/2){
	for (int j = i; j < B.size(); ++j) {
		cout<<" MINIMO F "<<j<< " eh = " <<minimo<<endl;
		somatorio = 0;

		for (int p = 1; p < j; ++p) {
			cout<<" Somatorio de W["<<p<< "] = "<<W[p]<<" eh = " <<somatorio<<endl;
			somatorio += W[p];
		}

		maxMin = max(0.0, min(l[j] - B[j], tempMaxViagemLeitura - R[j]));

		if(minimo > (somatorio + maxMin)){
			minimo = (somatorio + maxMin);
		}
	}
}

//	for (int i = 0; i < 6; ++i) {
//		cout<< "L ["<<i<<"] = "<<l[i]<<endl;
//		cout<< "L ["<<i<<"] = "<<l_Location[elementosDaRota[i]]<<endl;
//
//	}
//	cout<< "------------------------------------------------------------------------------------------"<<endl;
//
//
//	double somatorioW = 0, minimoFO, zero = 0;
//
//	//for (int j = 0; j < elementosDaRota.size(); j++) {//Para Cada Rota
//	for (int j = 0; j < W.size(); j++) {//Para Cada Rota
//		minimoFO = 99999999;
//		cout<<"R "<<R.at(j)<<endl;
//		if (elementosDaRota[j] == 0) {// G- -->> F0
//			cout<<"G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- "<<endl;
//			for (int p = 1; p < j; p++) {
//				somatorioW += W[p];
//				cout<<"W = "<<W[p]<<endl;
//			}
//			if (minimoFO > (somatorioW + min(l.at(j) - B.at(j),// <<--
//					tempMaxCaronaCliente_R - R.at(j))))
//				minimoFO = (somatorioW + min(l.at(j) - B.at(j),// <<--
//						tempMaxCaronaCliente_R - R.at(j)));
//			F[j] = min(somatorioW, minimoFO);
//
//
//		} else
//			if (elementosDaRota[j] != 0 && elementosDaRota[j] <= (numPontosLeitura / 2)){
//				cout<<"P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P "<<endl;
//				for (int p = 1; p < j; p++) {
//					somatorioW += W[p];
//					cout<<"W =>> "<<W[p]<<endl;
//
//				}
//				cout<<"Somatorio W = "<<somatorioW<<endl;
//				if (minimoFO > (somatorioW + min(l.at(j) - B.at(j), tempMaxCaronaCliente_R - R.at(j))))// <<--
//					minimoFO = (somatorioW + min(l.at(j) - B.at(j),	tempMaxCaronaCliente_R - R.at(j)));// <<--
//				F[j] = min(somatorioW, minimoFO);
//			}
//		//			if (j == 0) {// G-
//		//				cout<<"G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- G- "<<endl;
//		//				for (int p = 0; p < j; p++) {
//		//					somatorioW += W[p];
//		//				}
//		//				if (minimoFO > (somatorioW + min(l.at(j) - B.at(j),
//		//						tempMaxCaronaCliente_R - R.at(j))))
//		//					minimoFO = (somatorioW + min(l.at(j) - B.at(j),
//		//							tempMaxCaronaCliente_R - R.at(j)));
//		//				F[j] = min(somatorioW, minimoFO);
//
//			else{
//				cout<<"U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U U "<<endl;
//				F[j] = zero;
//			}
//
//		cout<<"-----------------IMPRIMINDO W ["<<j<<"] = "<<W[j]<<endl;
//		cout<<"-----------------IMPRIMINDO B ["<<j<<"] = "<<B[j]<<endl;
//		cout<<"-----------------IMPRIMINDO F ["<<j<<"] = "<<F[j]<<endl;
//	}
	cout<<"-----------------/////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\-----------------------"<<endl;

}

double calculaSomatorioWp(double somaWp, vector<double> W, int i) {
	cout << "Método Calcula Somatorio WP " << endl;
	for (int z = 1; z < W.size(); z++) {
		somaWp += W.at(z);
		cout<<"CALCULO DO W = "<< W.at(z);
	}
	return somaWp;
}


void calcularR(vector<double> B, vector<double> D, vector<double> R,
		vector<int> elementosDaRota) {
	cout << "Método Calcula R " << endl;

	for (int i = 0; i < elementosDaRota.size(); i++) {
		if (elementosDaRota[i] <= (numPontosLeitura / 2)){//Garante que ele seja um ponto de EMBARQUE

			cout<<"=====elementosDaRota (Embarque)======== "<< elementosDaRota[i] <<endl;

			if (elementosDaRota[i] != 0) {// ?? Redundante !
				int indiceDesembarque = indexOf(elementosDaRota,(numPontosLeitura / 2) + elementosDaRota.at(i));//elementosDaRota.indexOf(limiteDosEmbarques + elementosDaRota.at(i));
				//PEGAR O INDICE DO ELEMENTO APOS O LIMITE DO EMBARQUE DA ROTA
				cout<<"=====indiceDesembarque======== "<< indiceDesembarque <<endl;//Relacionada a lista da rota sem Garagens
				cout<<"=====ElementoDesembarque======== "<< elementosDaRota[indiceDesembarque] <<endl;
				cout<<"=====indiceDesembarque Na lista COM AS GARAGENS ======== "<< indiceDesembarque + 1 <<endl;
				//OBS B esta na lista com as garagens, logo insiro 1 para pular uma posicao, a que equivale a garagem inicial
				cout<<"R["<<i<<"] = ("<<(B[indiceDesembarque+1] - D[i+1])<<" >>"<<B[indiceDesembarque+1]<<" - "<< D[i+1]<<")"<<endl;
				R[i] = (B[indiceDesembarque+1] - D[i+1]);
			}
		}
	}

//	//	int i = 0;
//	//  for (vector<int> ::iterator it = elementosDaRota.begin(); it!= elementosDaRota.end(); it++) {//P e U
//	for (int i = 0; i < B.size(); i++) {
//		if (elementosDaRota[i] <= (numPontosLeitura / 2)){
//
//			cout<<"=====elementosDaRota (Embarque)======== "<< elementosDaRota[i] <<endl;
//			if (elementosDaRota[i] != 0) {
//				int indiceDesembarque = indexOf(elementosDaRota,(numPontosLeitura / 2) + elementosDaRota.at(i));//elementosDaRota.indexOf(limiteDosEmbarques + elementosDaRota.at(i));
//				//PEGAR O INDICE DO ELEMENTO APOS O LIMITE DO EMBARQUE DA ROTA
//				cout<<"=====indiceDesembarque======== "<< indiceDesembarque <<endl;
//				cout<<"=====ElementoDesembarque======== "<< elementosDaRota[indiceDesembarque] <<endl;
//				cout<<"R["<<i<<"] = ("<<(B[indiceDesembarque+1] - D[i+1])<<" >>"<<B[indiceDesembarque+1]<<" - "<< D[i+1]<<")"<<endl;
//				R[i] = (B[indiceDesembarque+1] - D[i+1]);
//			}
//		}
//		//i++;
//	}

}

void atualizaR(vector<double> B, vector<double> D, vector<double> R,
		vector<int> elementosDaRota, int j) {
	cout << "Método Atualiza R " << endl;
	for (int i = j; i < elementosDaRota.size(); i++) {
		if (elementosDaRota[i] <= (numPontosLeitura / 2)){//Garante que ele seja um ponto de EMBARQUE

			cout<<"=====elementosDaRota (Embarque)======== i ="<<i<<" elem ="<< elementosDaRota[i] <<endl;

			if (elementosDaRota[i] != 0) {// ?? Redundante !
				int indiceDesembarque = indexOf(elementosDaRota,(numPontosLeitura / 2) + elementosDaRota.at(i));//elementosDaRota.indexOf(limiteDosEmbarques + elementosDaRota.at(i));
				//PEGAR O INDICE DO ELEMENTO APOS O LIMITE DO EMBARQUE DA ROTA
				cout<<"=====indiceDesembarque======== "<< indiceDesembarque <<endl;//Relacionada a lista da rota sem Garagens
				cout<<"=====ElementoDesembarque======== "<< elementosDaRota[indiceDesembarque] <<endl;
				cout<<"=====indiceDesembarque Na lista COM AS GARAGENS ======== "<< indiceDesembarque + 1 <<endl;
				//OBS B esta na lista com as garagens, logo insiro 1 para pular uma posicao, a que equivale a garagem inicial
				cout<<"R["<<i<<"] = ("<<(B[indiceDesembarque+1] - D[i+1])<<" >>"<<B[indiceDesembarque+1]<<" - "<< D[i+1]<<")"<<endl;
				R[i] = (B[indiceDesembarque+1] - D[i+1]);
			}
		}
	}
}


double calculaFuncaoObjetivo(vector<Rota> &solucao) {
	cout << "Método Calcula Funcao Objetivo " << endl;
	double termoUmUm = 0, termoUmDois = 0, termoUmTres = 0, termoUmQuatro = 0,
			termoUmCinco = 0, //Os termos estao conforme a funcao
			termoDoisUm = 0, termoDoisDois = 0, termoDoisTres = 0, termoTresUm = 0, termoTresDois = 0;
	vector<int> elementosDaRota;
	vector<double> A, B, D, W, R, T, Q, e , l;
	// int k = 0;
	for (int k = 0; k < solucao.size(); k++) {//Para cada SOLUCAO
		//for (vector<int> ::iterator it = elementosDaRota.begin(); it!= elementosDaRota.end(); it++) {//P e U
		cout << "Entar no for"<<endl;

		cout << "Tamanho da solucao=====>  " << solucao.size() << endl;
		Rota rota = solucao.at(k);
		//Seleciona os Dados da ROTA
		elementosDaRota = solucao.at(k).getRota();
		cout << "QUANTIDADE DE ELEMENTOS NA ROTA = "<< elementosDaRota.size()<<endl;
		A = solucao.at(k).getA();
		B = solucao.at(k).getB();
		D = solucao.at(k).getD();
		W = solucao.at(k).getW();
		R = solucao.at(k).getR();
		T = solucao.at(k).getT();
		Q = solucao.at(k).getQ();
		//Somatorio dos veiculos  ===================================================== T 1,2
		cout << "Somatorio dos Veiculos = "<< termoUmDois<<endl;
		termoUmDois += 1;

		cout << "Entar no for"<<endl;
		cout<<"Tamanho do elementosDaRota ="<<elementosDaRota.size()<<endl;
		for (int i = 0; i < B.size(); i++) {// Para N = G- u P u G+
			cout << "========FO B=" << B[i] << endl;
			cout << "========FO D=" << D[i] << endl;
			cout << "========FO W=" << W[i] << endl;
			cout << "========FO R=" << R[i] << endl;
			cout << "========FO T=" << T[i] << endl;
			cout << "========FO Q=" << Q[i] << endl;
			//			e = rota.getE();
			//			l = rota.getL();
			int aux = 0;
			cout << elementosDaRota.size()<<endl;
			for (int j = 0; j < elementosDaRota.size(); j++) {// Para P u U
				cout << "aqui"<<j<<endl;
				aux = elementosDaRota[j];//Retorna o id
				//e.insert(i,e_Location[aux]);
				//l.insert(i,l_Location[aux]);
				e.push_back(inicioJanelaLeitura[j]);
				l.push_back(fimJanelaLeitura[j]);

				//				s.add(i,s_Location[aux]);
				//				acao.add(i, acao_Location[aux]);
			}
			cout << "Fim for"<<endl;
			//Somatorio das distancias ===================================================== T 1,1
			cout << "Somatorio das distancias tamanho de A "<< A.size()<<endl;
//			for (int j = 0; j < elementosDaRota.size() - 1; j++) {
//				if (elementosDaRota[j] != elementosDaRota[j + 1])
//					termoUmUm += distancias[elementosDaRota.at(j)][elementosDaRota.at(j + 1)];
//			}

			for (int j = 0; j < A.size()-1; j++) {
				cout<<"Aqui "<<j<< endl;
				if(j == 0){//Garagem Inicial -->> Primeira requisicao
					termoUmUm += distancias[0][elementosDaRota[j]];
					cout<<"G- p Elemento "<<elementosDaRota[j]<<endl;
				}else{
					if(j < A.size()-2){
						termoUmUm += distancias[elementosDaRota.at(j-1)][elementosDaRota.at(j)];
						cout<<" Elemento "<<elementosDaRota[j-1]<<" Elemento 2 "<<elementosDaRota[j]<<endl;
					}else{//Primeira requisicao  -->> Garagem Final
						termoUmUm += distancias[elementosDaRota.at(j-1)][garagemFinal];
						cout<<" Elemento p G+ "<<elementosDaRota[j-1]<<endl;
					}
				}
			}
		}
////////
			//Termo         =========================================================================== T 1,3
			//Somatorio dos tempos de inicio da viagem da garagem inicial menos o tempo de chegada na garagem final
			cout << "Somatorio dos tempos de inicio da viagem da garagem inicial menos o tempo de chegada na garagem final"<<endl;
			termoUmTres += B[garagemFinal] - D[garagemInicial];

			//Termo         =========================================================================== T 1,4
			cout << "T 1 4 = Somatorio do tempo de viagem e Somatorio do tempo de espera"<<endl;
			for (int i = 1; i < elementosDaRota.size() +1; i++) {//Tiramos as garagens
				if (elementosDaRota[i] <= (numPontosLeitura / 2)) {//i E P
					//Somatorio do tempo de viagem
					cout<<i<<" =========<<<<>>>>=====  ELEMENTOS DA ROTA MENORES QUE 25 ="<< elementosDaRota[i] <<endl;
					termoUmQuatro += R.at(i);
				}
				//Termo         =========================================================================== T 1,5
				//Somatorio do tempo de espera
				termoUmCinco += W.at(i);//P ou U
				cout<< " W ["<<i<<"] = "<<W.at(i)<<endl;
			}

			//==================== Passamos para o segundo termo
			cout << "Somatorio1"<<endl;
			//Termo         =========================================================================== T 2,1
			//Calcula o somatorio
			termoDoisUm += max(	0.0, (B.at(garagemFinal) - D.at(garagemInicial)) - tempMaxRotaLeitura);//rota.getTempoTotalDestaRota());//TODO VERIFICAR O T"_K

			cout << "Somatorio2"<<endl;
			//Termo         =========================================================================== T 2,2
			//Calcula o somatorio
			int tempoMaxViagemCliente = rota.getTempoMaximoDeViagemPermitido();
			//cout<< "TEMP MAX DURACAO DA ROTA = "<<tempMaxViagemLeitura<<endl;
			for (int i = 1; i < elementosDaRota.size() +1; i++) {
				if (elementosDaRota.at(i-1) <= (numPontosLeitura / 2))
					termoDoisDois += max(0.0, (R.at(i) - tempoMaxViagemCliente));//tempoMaxViagemCliente));
			}

			//Calcula o somatorio
			//double[] tempoMaxEsperaNoPonto = rota.getTempoMaximoDeEspera();
			//Termo         =========================================================================== T 2,3
			for (int i = 1; i < elementosDaRota.size()+1; i++) {
				//if (elementosDaRota.at(i) < (numPontosLeitura / 2))
					termoDoisTres += max(0.0, (W.at(i) - W_TempoMaximo_Espera));
			}
			cout << "Somatorio3"<<endl;


			//Termo         =========================================================================== T 2,4

			double somatorio = 0;

			//	cout<<"Entra no laco";

			for (int i = 0; i < elementosDaRota.size(); i++) {
				for (int j = 0; j < elementosDaRota.size(); j++) {
					if(i!= j && j != (numPontosLeitura/2) - i){
						somatorio += infoPontoLeitura[elementosDaRota[j]];
						//						if (somatorio > cargaMaximaDoVeiculo) {
						cout<<"Somatorio = "<< somatorio<<" ELemento i "<< elementosDaRota[i]<<" ELemento j "<< elementosDaRota[j]<<" inf ponto "<<infoPontoLeitura[elementosDaRota[j]]<< endl;
					}
				}

			}

			termoTresUm += max(0.0, somatorio - cargaMaximaDoVeiculo);
			cout<<"TERMO 3 1  = "<<termoTresUm<< endl;
			//-------------------------------------------------------------------------------------------
//			double somatorio = 0;
//			//int* acao = acao_Location;
//			cout<<"Entra no laco";
//			//			System.out.println("A Carga M√°xima do ve√≠culo √© "+ cargaMaximaDoVeiculo);
//			for (int j = 1; j < elementosDaRota.size(); j++) {
//				//	System.out.println("ELemento de tamanho"+ elementosDaRota.size()+"esta em "+i);
//				//				for (int j = 1; j < elementosDaRota.size()-1; j++) {
//				//					if(i!= j && j != limiteDosEmbarques - i){
//				somatorio += infoPontoLeitura[elementosDaRota[j]];
//				if (somatorio > cargaMaximaDoVeiculo) {
//					termoTresUm += somatorio - cargaMaximaDoVeiculo;
//				}
//				//System.out.println("Termo "+i+"eh "+somatorio);
//				//						System.out.println("Acao "+acao[elementosDaRota.get(i)]);
//				//					}
//				//				}
//			}
		//-------------------------------------------------------------------------------------------

			//			termoTresUm += Math.max(0, somatorio - cargaMaximaDoVeiculo);


			//			for (int i = 1; i < elementosDaRota.size()-1; i++) {
			//				double somatorio = 0; int[] acao = acao_Location;
			//				System.out.println("ELemento de tamanho"+ elementosDaRota.size()+"esta em "+i);
			//				for (int j = 1; j < elementosDaRota.size()-1; j++) {
			//					if(i!= j && j != limiteDosEmbarques - i){
			//						somatorio += acao[elementosDaRota.get(i)];
			//						System.out.println("Acao "+acao[elementosDaRota.get(i)]);
			//					}
			//				}
			//				termoTresUm += Math.max(0, somatorio - cargaMaximaDoVeiculo);
			//				System.out.println("Termo "+i+"eh "+somatorio);
			//
			//			}
			cout << "Somatorio4"<<endl;
			//Somatorio
			for (int i = 0; i < A.size(); i++) {
				cout << "I "<<i<<endl;
				if((i == 0) || (i == A.size()-1)){
					cout<<" IF Elemento da rota = "<<i<<" e = "<<e_Location[garagemInicial]<<" B = "<<B[i]<<" "<< B.at(i)<< endl;
					termoTresDois += max(0.0,(e_Location[garagemInicial] - B.at(i)) + max(0.0, B.at(i) - l_Location[garagemInicial]));
				}else{
					cout<<" Else Elemento da rota = "<<elementosDaRota[i-1]<<" e = "<<e_Location[elementosDaRota[i-1]]<<" l = "<< l_Location[elementosDaRota[i-1]]<<" B = "<<B[i]<<endl;
					termoTresDois += max(0.0,(e_Location[elementosDaRota[i-1]] - B.at(i))) + max(0.0, (B.at(i) - l_Location[elementosDaRota[i-1]]));
				}
				cout<<"Termo Tres Dois = "<< termoTresDois<< endl;
			}

		//			funcaoObjetivo =termoUmUm() + w1*termoUmDois()+termoUmTres()+termoUmQuatro()+termoUmCinco();
		cout<<"Calcula Funcao Objetivo";
		funcaoObjetivo = w0 * termoUmUm + w1 * termoUmDois + w2 * termoUmTres
				+ w3 * termoUmQuatro + w4 * termoUmCinco + b0 * termoDoisUm
				+ b1 * termoDoisDois + b2 * termoDoisTres + b3 * termoTresUm
				+ b4 * termoTresDois;
		double ResultadoSemPesos_FO =termoUmUm +  termoUmDois +  termoUmTres
				+ termoUmQuatro +  termoUmCinco +  termoDoisUm
				+ termoDoisDois +  termoDoisTres + termoTresUm
				+  termoTresDois;
		cout<<">>>> Funcao Objetivo SEM OS PESOS = "<< ResultadoSemPesos_FO<< endl;
		//    k++;
	}
	cout << "T11 " << termoUmUm << "\n T12 " << termoUmDois << "\n T13 "
			<< termoUmTres << "\n T14 " << termoUmQuatro << "\n T15 "
			<< termoUmCinco << "\n T21 " << termoDoisUm << "\n T22 "
			<< termoDoisDois << "\n T23 " << termoDoisTres << "\n T31 "
			<< termoTresUm << "\n T32 " << termoTresDois << endl;
	cout << "\n Funcao Objetiva == valor: " << funcaoObjetivo << endl;
	cout
	<< " ======================== Fim do Calcula Funcao Objetivo ========================"
	<< endl;

	return funcaoObjetivo;
}

vector<Rota> & geraAleatoriamente(vector<Rota> &sol){
	cout<<" ======================== Inicio Gera Aleatoriamente ========================"<<endl;
	int opcaoRandomica = (int) ((rand() % 3));
	vector<Rota> solucaoAux;
	switch (opcaoRandomica) {
	case 0:

		solucaoAux = reordenarRota(sol);//Passando a lista original
		cout<<"====>>>>1 Solucao Retorno "<<endl;
		rotaToString(solucaoAux);
		break;

	case 1:
		//solucaoAux =realocaPonto(sol); //Copiando a lista e passando como parametro
		solucaoAux =realocaPonto(sol);
		cout<<"====>>>>2 Solucao Retorno "<<endl;
				rotaToString(solucaoAux);
		break;

	case 2:
		solucaoAux =trocaPontos(sol);
		cout<<"====>>>>3 Solucao Retorno "<<endl;
				rotaToString(solucaoAux);
		break;

	default:
		solucaoAux =realocaBlocosEmbarque(sol);
		cout<<"====>>>>4 Solucao Retorno "<<endl;
				rotaToString(solucaoAux);
		break;
	}
	cout<<" ======================== Fim do Gera Aleatoriamente ========================"<<endl;

	return solucaoAux;

}


/*
 *     ESTRUTURAS DAS VIZINHANCAS
 */

/**
 * Reordena uma única rota da Solução
 *
 * @param so Solução, conjunto de rotas
 * @return so Solução com uma rota reordenada
 */

vector<Rota> & reordenarRota(vector<Rota> solucao){//&solucao){
	cout<<"Entrou no metodo reordena"<<endl;
	//rand() % numVeicLeitura;
	int rotaRandomica = (int) (rand() % solucao.size()),
			indiceDesembarque,
			indiceRandomico,
			indiceEmbarque,
			elementoTroca, desembarqueElemento, embarqueElemento;

	vector<int> rota = solucao[rotaRandomica].getRota();

	if(rota.size() <2)	return solucao;

	do{
		indiceRandomico = (int) (rand() % rota.size());
	}while(indiceRandomico == rota.size());
	cout<<"Rota Randomica = "<< rotaRandomica <<endl;
	cout<< "Indice Radomico "<< indiceRandomico << " tamanho da Rota "<< rota.size()<< endl;

	elementoTroca = rota.at(indiceRandomico);
	cout<<"Elemento Troca = "<< elementoTroca <<endl;

	rotaToString(solucao);
	do{
		indiceEmbarque = (int) (rand() % rota.size());
		indiceDesembarque = (int) (rand() % rota.size());
	}while((indiceRandomico == indiceEmbarque) ||
			(indiceEmbarque >= indiceDesembarque ) ||
			(indiceDesembarque >= (rota.size()-1)));
	//cout<<"4 "<<endl;
	//cout<< "Indice Embarque "<< indiceEmbarque<< " Indice Desembarque "<< indiceDesembarque<< " tamanho da Rota "<< rota.size()<< endl;
	cout<< "Indice Elemento Troca "<< elementoTroca<<" Limite embarque desembarque "<<(numPontosLeitura/2)<< endl;

	if(elementoTroca <= (numPontosLeitura/2)){//O Id eh Embarque
		cout<<"IF elemento troca = "<< elementoTroca << " Tamanho da Rota "<< rota.size() <<endl;
		desembarqueElemento = elementoTroca + (numPontosLeitura/2);// ID referente ao desembarque da requisicao
		indiceDesembarque = retornaIndice(rota, desembarqueElemento);
		rota.erase(rota.begin() + indiceRandomico );//Apaga o ID do embarque na rota

		solucao[rotaRandomica].setRota(rota);
		rotaToString(solucao);

		cout<<"Rota sz "<< rota.size()<<endl;

		//indiceDesembarque
		//vector<int>::iterator it = std::search(rota.begin(), rota.end(), desembarqueElemento);//rota.at(desembarqueElemento);

		cout<<">>>  === IF Rota selecionada "<< rotaRandomica <<" desembarque = "<< desembarqueElemento<<" indice desembarque "<<indiceDesembarque <<" Tamanho da Rota "<< rota.size() <<endl;

		do{
			indiceEmbarque = (int) (rand() % rota.size());
			//indiceDesembarque = (int) (rand() % rota.size());
		}while((indiceRandomico == indiceEmbarque) ||//O indice anterior do elemento de troca diferente do indice atual
				(indiceEmbarque > indiceDesembarque )); //O elemento tem que ter a posicao anterior ao desembarque
		cout<<"Posicao do elemento a ser trocado inicial= "<< indiceRandomico<<endl;
		cout<<"Posicao do elemento a ser trocado nova= "<< indiceEmbarque<<endl;
		cout<<"Posicao do respectivo desembarque= "<< indiceDesembarque<<endl;

		rota.insert(rota.begin()+indiceEmbarque, elementoTroca);//Embarque
		//rota.insert(rota.begin(),indiceDesembarque, elementoTroca +(numPontosLeitura/2));//Desembarque
		solucao[rotaRandomica].setRota(rota);
		rotaToString(solucao);
		cout<<"IF "<<endl;
	}else{
		cout<<"ELSE "<<endl;
		embarqueElemento = elementoTroca - (numPontosLeitura/2);
		indiceEmbarque = retornaIndice(rota, embarqueElemento);
		cout<<">>>  === IF Rota selecionada "<< rotaRandomica <<" Embarque = "<< embarqueElemento<<" indice desembarque "<<indiceDesembarque <<" Tamanho da Rota "<< rota.size() <<endl;
		rota.erase(rota.begin() + indiceRandomico);
		solucao[rotaRandomica].setRota(rota);
		rotaToString(solucao);

		cout<<"ELSE "<<endl;
		do{
			indiceDesembarque = (int) (rand() % rota.size());
		}while((indiceRandomico == indiceDesembarque) ||//O indice anterior do elemento de troca diferente do indice atual
				(indiceEmbarque > indiceDesembarque )); //O elemento tem que ter a posicao anterior ao desembarque

		rota.insert(rota.begin() + indiceDesembarque, elementoTroca);//Desembarque
		solucao[rotaRandomica].setRota(rota);
		cout<<"Posicao do elemento a ser trocado inicial= "<< indiceRandomico<<endl;
		cout<<"Posicao do elemento a ser trocado nova= "<< indiceEmbarque<<endl;
		cout<<"Posicao do respectivo desembarque= "<< indiceDesembarque<<endl;
		rotaToString(solucao);
		cout<<"ELSE "<<endl;
	}
	//		if(verificaViabilidade(rota1)){
	//			so.get(nRota1Randomica).setRota(rota1);
	//		}
	cout<< " ======================== Fim do Reordena Rota ========================"<< endl;
	rotaToString(solucao);
	return solucao;
}

int retornaIndice(vector<int> &rota,int elemento){
	for (int var = 0; var <= rota.size(); ++var) {
		if(elemento == rota[var]){
			return var;
		}
	}
	return 0;
}


/**
 * Realoca uma requisicao( embarque e respectivo desembarque) de uma rota1 para a rota2
 * @param so
 * @return
 */
vector<Rota> & realocaPonto(vector<Rota> solucao){//&solucao){
	cout<<" ======================== Inicio Realoca Ponto ========================"<<endl;
	int nRota1Randomica = (int) (rand() % solucao.size()),
			nRota2Randomica, indiceEmbarque, posicaoRandomica, indiceDesembarque, elementoDesembarque, elementoEmbarque;
	do{
		nRota2Randomica = (int) ((rand() % solucao.size()));
	}while(nRota1Randomica == nRota2Randomica ); // Temos dois indices diferentes para obtermos as rotas diferentes

	//Seleciona as duas rotas de forma aleatorias
	vector<int> rota1 = solucao[nRota1Randomica].getRota(),
			rota2 = solucao[nRota2Randomica].getRota();

	//	if(!verificaSeTemVaga(rota1))
	//		return solucao;

	if( rota1.size() == 2 ||  rota2.size() == 2)
		return solucao;
	do{
		indiceEmbarque = (int)(rand() % rota1.size());//Seleciona qualquer um dos pontos da rota
		elementoEmbarque = rota1[indiceEmbarque];
	}while(elementoEmbarque > (numPontosLeitura/2));


	rotaToString(solucao);

	elementoDesembarque = (rota1[indiceEmbarque] + (numPontosLeitura/2));
	indiceDesembarque = retornaIndice(rota1, elementoDesembarque);

	cout<< "Rota 1 = "<< nRota1Randomica << " Rota 2 = "<< nRota2Randomica<< endl;
	cout<< "Indice de embarque a remover "<< indiceEmbarque <<" Incide desembarque a remover "<< indiceDesembarque<<endl;
	cout<< "Elemento de embarque a remover "<< elementoEmbarque <<" Elemento desembarque a remover "<< elementoDesembarque<<endl;

	//	cout<<"Posicao do elemento a ser trocado inicial= "<< indiceEmbarque <<endl;
	//	cout<<"Posicao do elemento a ser trocado nova= "<< indiceEmbarque<<endl;
	//	cout<<"Posicao do respectivo desembarque= "<< indiceDesembarque<<endl;

	cout<< "Resultado rota 1 .begin()"<< *rota1.begin() << endl;//<========================== PQ ???
	cout<< "Resultado rota 1 .begin()"<< *rota1.begin() + indiceEmbarque<< endl;
	cout<< "Resultado rota 1 .begin()"<< *rota1.begin() + indiceDesembarque-1<< endl;

	rota1.erase(rota1.begin() + indiceEmbarque);
	cout<<"Aqui"<<endl;

	rota1.erase(rota1.begin() + indiceDesembarque-1);
	solucao[nRota1Randomica].setRota(rota1);
	rotaToString(solucao);

	//Atualiza os valores dos indices para serem inseridos na outra rota
	do{
		indiceEmbarque = (int)(rand() % rota2.size());//Seleciona qualquer um dos pontos da rota
		indiceDesembarque = (int)(rand() % rota2.size());//Seleciona qualquer um dos pontos da rota

	}while(indiceEmbarque>= indiceDesembarque);//elementoEmbarque <= elementoDesembarque);

	rota2.insert(rota2.begin()+indiceEmbarque, elementoEmbarque);//Embarque
	rota2.insert(rota2.begin()+indiceDesembarque, elementoDesembarque);//Desembarque

	solucao[nRota2Randomica].setRota(rota2);
	rotaToString(solucao);
	vector<double> A(rota1.size(),0.0), B(rota1.size(),0.0),D(rota1.size(),0.0),R(rota1.size(),0.0),
			W(rota1.size(),0.0),F(rota1.size(),0.0),Q(rota1.size(),0.0);
	solucao[nRota1Randomica].setVectorA(A);
	solucao[nRota1Randomica].setVectorB(B);
	solucao[nRota1Randomica].setVectorD(D);
	solucao[nRota1Randomica].setVectorR(R);
	solucao[nRota1Randomica].setVectorW(W);
	solucao[nRota1Randomica].setVectorF(F);
	solucao[nRota1Randomica].setVectorQ(Q);

	//solucao[nRota1Randomica].setVectorA(A);
	cout<<"1 Elemento A da Rota "<<solucao[nRota1Randomica].getA().size() <<endl;
	vectorToString(solucao[nRota1Randomica].getA());

	vector<double> A2(rota2.size(),0.0), B2(rota2.size(),0.0),D2(rota2.size(),0.0),R2(rota2.size(),0.0),
			W2(rota2.size(),0.0),F2(rota2.size(),0.0),Q2(rota2.size(),0.0);
	solucao[nRota2Randomica].setVectorA(A2);
	solucao[nRota2Randomica].setVectorB(B2);
	solucao[nRota2Randomica].setVectorD(D2);
	solucao[nRota2Randomica].setVectorR(R2);
	solucao[nRota2Randomica].setVectorW(W2);
	solucao[nRota2Randomica].setVectorF(F2);
	solucao[nRota2Randomica].setVectorQ(Q2);

	cout<<"2 Elemento A da Rota  "<<solucao[nRota2Randomica].getA().size() <<endl;
	vectorToString(solucao[nRota2Randomica].getA());

	//TODO Fazer o restante das alocacoes
	return solucao;
}


/**
 * Troca-se as requisicoes (embarque e respectivo desembarque)
 *
 * @param so
 * @return
 */
vector<Rota> & trocaPontos(vector<Rota> solucao){//&solucao){
	cout<<" ======================== Inicio Troca Pontos ========================"<<endl;
	int nRota1Randomica = (int) (rand() % solucao.size()),
			nRota2Randomica, posicaoRandomica, indiceEmbarque1, indiceDesembarque1,
			indiceEmbarque2, indiceDesembarque2, elementoDesembarque1, elementoEmbarque1,
			elementoDesembarque2, elementoEmbarque2;
	do{
		nRota2Randomica = (int) ((rand() % solucao.size()));
	}while(nRota1Randomica == nRota2Randomica ); // Temos dois indices diferentes para obtermos as rotas diferentes

	//Seleciona as duas rotas de forma aleatorias
	vector<int> rota1 = solucao[nRota1Randomica].getRota(),
			rota2 = solucao[nRota2Randomica].getRota();

	//	if(!verificaSeTemVaga(rota1))
	//		return solucao;

	if( rota1.size() == 2 ||  rota2.size() == 2)
		return solucao;

	do{
		indiceEmbarque1 = (int) (rand() % rota1.size());//Seleciona qualquer um dos pontos da rota
		elementoEmbarque1 = rota1[indiceEmbarque1];
	}while(elementoEmbarque1 > (numPontosLeitura/2));

	//cout<<"Ate aqui "<<endl;
	rotaToString(solucao);

	elementoDesembarque1 = (rota1[indiceEmbarque1] + (numPontosLeitura/2));
	indiceDesembarque1 = retornaIndice(rota1, elementoDesembarque1);


	do{
		indiceEmbarque2 = (int)rand() % (rota2.size());//Seleciona qualquer um dos pontos da rota
		elementoEmbarque2 = rota2[indiceEmbarque2];
	}while(elementoEmbarque2 > (numPontosLeitura/2));

	rotaToString(solucao);

	elementoDesembarque2 = (rota2[indiceEmbarque2] + (numPontosLeitura/2));
	indiceDesembarque2 = retornaIndice(rota2, elementoDesembarque2);
	cout<< "Rota 1 = "<< nRota1Randomica << " Rota 2 = "<< nRota2Randomica<< endl;
	cout<< "Indice de embarque a remover "<< indiceEmbarque1 <<" Incide desembarque a remover "<< indiceDesembarque1 <<endl;
	cout<< "Elemento de embarque a remover "<< elementoEmbarque1 <<" Elemento desembarque a remover "<< elementoDesembarque1 <<endl;
	//Apaga os elementos das suas respectivas rotas
	cout<<" Rota 1 = "<< *rota1.begin()<<endl;
	cout<<" Rota 1 + indice = "<< *rota1.begin() + indiceEmbarque1<<endl;
	rota1.erase(rota1.begin() + indiceEmbarque1);
	rota1.erase(rota1.begin() + indiceDesembarque1-1);
	cout<<"Ate aqui "<<endl;

	rota2.erase(rota2.begin() + indiceEmbarque2);
	rota2.erase(rota2.begin() + indiceDesembarque2-1);
	cout<<" Rota 2 = "<< *rota2.begin()<<endl;
	cout<<" Rota 2 + indice = "<< *rota2.begin() + indiceEmbarque2<<endl;



	cout<< "Indice de embarque a remover "<< indiceEmbarque2 <<" Incide desembarque a remover "<< indiceDesembarque2 <<endl;
	cout<< "Elemento de embarque a remover "<< elementoEmbarque2 <<" Elemento desembarque a remover "<< elementoDesembarque2 <<endl;

	//Seleciona os novos indices de embarques e desembarques
	do{
		cout<<"Ate aqui "<<endl;

		indiceEmbarque1 = (int)(rand() % rota2.size());//Seleciona qualquer um dos pontos da rota para o embarque
		indiceDesembarque1 = (int)(rand() % rota2.size());//Seleciona qualquer um dos pontos da rota para o desembarque
		cout<< "Indice de embarque a remover "<< indiceEmbarque1 <<" Incide desembarque a remover "<< indiceDesembarque1 <<endl;

	}while(indiceEmbarque1 >= indiceDesembarque1);
	cout<<"Ate aqui 2"<<endl;

	do{cout<<"Ate aqui While"<<endl;
	indiceEmbarque2 = (int)(rand() % rota1.size());//Seleciona qualquer um dos pontos da rota para o embarque
	indiceDesembarque2 = (int)(rand() % rota1.size());//Seleciona qualquer um dos pontos da rota para o desembarque
	cout<< "Indice de embarque a remover "<< indiceEmbarque2 <<" Incide desembarque a remover "<< indiceDesembarque2 <<endl;
	}while(indiceEmbarque2  >= indiceDesembarque2);
	cout<<"Ate aqui "<<endl;
	//Insercao nas rotas
	rota2.insert(rota2.begin()+indiceEmbarque1, elementoEmbarque1);//Embarque da rota1 na rota2
	rota2.insert(rota2.begin()+indiceDesembarque1, elementoDesembarque1);//Desembarque da rota1 na rota2

	rota1.insert(rota1.begin()+indiceEmbarque2, elementoEmbarque2);//Embarque da rota2 na rota1
	rota1.insert(rota1.begin()+indiceDesembarque2, elementoDesembarque2);//Desembarque da rota2 na rota1

	//	 	cout<< "Rota 1 = "<< nRota1Randomica << " Rota 2 = "<< nRota2Randomica<< endl;
	//	 	cout<< "Indice de embarque a remover "<< indiceEmbarque <<" Incide desembarque a remover "<< indiceDesembarque<<endl;
	//	 	cout<< "Elemento de embarque a remover "<< elementoEmbarque <<" Elemento desembarque a remover "<< elementoDesembarque<<endl;
	solucao[nRota1Randomica].setRota(rota1);
	solucao[nRota2Randomica].setRota(rota2);
	rotaToString(solucao);

	//TODO MODIFICAR
	cout<<" ======================== Fim Troca Pontos ========================"<<endl;

	return solucao;

}

vector<Rota> & realocaBlocosEmbarque(vector<Rota>  solucao){//&solucao){
	cout<<"Entrou no metodo Realoca Blocos Embarque"<<endl;
	//rand() % numVeicLeitura;
	int rotaRandomica = (int) (rand() % solucao.size()),
			indiceDesembarque,
			indiceRandomico,
			indiceEmbarque,
			elementoTroca, desembarqueElemento, embarqueElemento;

	vector<int> rota = solucao[rotaRandomica].getRota();

	if(rota.size() <=2)	return solucao;

	vector<int> rotaAux;
	int indiceDeParada = 0;
	for (int i = 0; i < rota.size(); ++i) {
		if(rota[i] <= (numPontosLeitura/2)){
			rotaAux.push_back(rota[i]);
			indiceDeParada = i;
		}else
			break;
	}
	rotaToString(solucao);

	rota.erase(rota.begin(),rota.begin() + indiceDeParada+1);
	solucao[rotaRandomica].setRota(rota);
	rotaToString(solucao);

	for (int i = 0; i < rotaAux.size(); ++i) {
		cout<<"Tamanho da rota aux = "<< rotaAux.size()<<" i = "<< i << " rota aux = "<< rotaAux[i] << endl;
		rota.insert(rota.begin(), rotaAux[i]);
	}

	solucao[rotaRandomica].setRota(rota);
	rotaToString(solucao);

	return solucao;
}
//		System.out.println(" ======================== Fim do Realoca Blocos ========================");
//		return so;
//
//	}

void vectorToString(vector<double> solucao) {
	cout<<"---------------------------------------------------------------------------"<<endl;
	cout << "[";
	for (int i = 0; i < solucao.size(); i++) {
		cout << " " << solucao[i];
	}
	cout << "]" << endl;

}

/********************************************************************************************************************************
 ********************************************************************************************************************************
 ***************************** <<             META HEURISTICA           >> ****************************************************************
 ********************************************************************************************************************************
 */

//Meta Heuristica ILS-MRD

void ILS(vector<Rota> &solucao, int maxIter, int maxIterILS, int kpMax, int delta){
	cout<<" ======================== Inicio do ILS ========================"<<endl;

	vector<Rota> s_linha ; //Solucao s' conjunto de rotas
	vector<Rota> s_duaslinhas;//Solucao s'' conjunto de rotas
	solucaoInicial(solucao);//Cria a solucao inicial
	//heuristicaDeProgramacao(solucao);
	cout<<"Cria Solucao Inicial"<<endl;
	vector<Rota> so = solucao;//Atribue a so a solucao inicial
	rotaToString(so);
	s_linha = MRD(so, maxIterILS);
	heuristicaDeProgramacao(s_linha);
	//solucaoInicial();

	int kp = 0;
	int iter = 0, melhorIter = 0;
	cout<<"Inicia o primeiro While"<<endl;
	while (kp < kpMax){
		iter = melhorIter;
		cout<<"Inicia o Segundo While"<<endl;
		while(iter < maxIter){
			iter = iter + 1;
			cout<<"Iteracao ILS eh: "<<iter<<" ================"<<endl;
			//TODO Perturbqacao
			s_linha = pertubar(s_linha);
			s_duaslinhas = MRD(so, maxIterILS);//TODO METODO DO MRD
			heuristicaDeProgramacao(s_duaslinhas);
			float s_linhaFO = calculaFuncaoObjetivo(s_linha), s_duasLinhasFO = calculaFuncaoObjetivo(s_duaslinhas);
			if ( s_linhaFO < s_duasLinhasFO ){
				s_linha = s_duaslinhas;
				melhorIter = iter;
				kp = 0;
			}
		}
		kp = kp + delta;
	}
//
		cout<<"Valor da função objetivo é: "<<funcaoObjetivo<<endl;
//		System.out.println("Rotas ==>>");
//		imprimeRotas(s_linha);
//		cout<<" ======================== Fim do ILS ========================"<<endl;
	}

vector<Rota> pertubar(vector<Rota> &solucao){
//TODO Ver como selecionar as 2 piores rotas!!!!
}

//====================================
vector<Rota> MRD(vector<Rota> &so, int maxIterILS) {
	int iter = 0;
	vector<Rota> s_linha;
	double foSLinha = 0, foSO = 0;
		while(iter < maxIterILS){
			iter = iter + 1;
			cout<<"Iteracao n "<< iter<<endl;
			s_linha = geraAleatoriamente(so);
			cout<<"Imprime SO "<<endl;
			rotaToString(so);
			cout<<"Imprime S_Linha "<<endl;
			rotaToString(s_linha);

			heuristicaDeProgramacao(s_linha);
			foSLinha = calculaFuncaoObjetivo(s_linha);
			foSO = calculaFuncaoObjetivo(so);
			if(foSLinha < foSO){//(calculaFuncaoObjetivo(s_linha) < calculaFuncaoObjetivo(so)){
				so = s_linha;//
				iter = 0;
			}
		}
		cout<<" ======================== Fim do MRD ========================"<<endl;

		return so;

}

/********************************************************************************************************************************
 ********************************************************************************************************************************
 ***************************** <<             MAIN            >> ****************************************************************
 ********************************************************************************************************************************
 */
int main() {
	srand(time(NULL));
	cout << "Sucesso == \n";
	cout << "Carrega Dados" << endl;
	carregaDados();
	cout << "Inicializa Rotas" << endl;
	vector<Rota> solucion;
	inicializaRotas(solucion);

	int maxIter = 100,maxIterILS= 100, kpMax= 100, delta=0.5;
	cout<<"Entra no ILS"<<endl;
	ILS(solucion,maxIter,maxIterILS, kpMax, delta);
	//inicializaRotas(solucion);
	cout << "Inicia Solucao Inicial" << endl;
//	solucaoInicial(solucion);
//	rotaToString(solucion);
	heuristicaDeProgramacao(solucion);
//	calculaFuncaoObjetivo(solucion);
	//reordenarRota(solucion);
	//geraAleatoriamente(solucion);
//	heuristicaDeProgramacao(solucion);
	//calculaFuncaoObjetivo(solucion);
	//realocaPonto(solucion);
	//realocaBlocosEmbarque(solucion);
	cout<<"Rota final"<<endl;
	rotaToString(solucion);
	cout<<"FIM DO MAIN"<< endl;
	return (EXIT_SUCCESS);
}

void rotaToString(vector<Rota> &solucao) {
	vector<int> rota;
	cout<<"---------------------------------------------------------------------------"<<endl;
	for (int i = 0; i < solucao.size(); i++) {
		rota = solucao[i].getRota();
		cout << "[";
		for (int j = 0; j < rota.size(); j++) {
			cout << " " << rota[j];
		}
		cout << "]" << endl;
	}
}

/**
 * Metodo responsavel por ler as instancias de entrada
 *
 */
void carregaDados() {
	//Le os dados do arquivo de leitura
	puts("Inicio do main");
	// Carregando dados de entrada

	ifstream
	Instancia(
			"/home/daniel/workspace/DARP_Mestrado/src/Instancias/instancia.txt"); // Abre arquivo para leitura

	if (!Instancia) {
		cerr << "Arquivo nao pode ser aberto" << endl;
	}

	puts("Inicio var inst");
	//Variaveis da instancia
	Instancia >> numVeicLeitura;
	Instancia >> numPontosLeitura;
	Instancia >> tempMaxRotaLeitura;
	Instancia >> capacidadeVeiculoLeitura;
	Instancia >> tempMaxViagemLeitura;

	cout<<"Quantidade de Veiculos = "<<numVeicLeitura<<endl;
	cout<<"Quantidade de Pontos = "<<numPontosLeitura<<endl;
	cout<<"Tempo max da rota de um veiculo = "<<tempMaxRotaLeitura<<endl;
	cout<<"Capacidade do Veiculos = "<<capacidadeVeiculoLeitura<<endl;
	cout<<"Tempo max da rota de um  = "<<tempMaxViagemLeitura<<endl;


	numPontosLeitura++;

	idPontoLeitura = new int[numPontosLeitura + 1]; // ponto referente a garagem unica
	infoPontoLeitura = new int[numPontosLeitura + 1];
	coordXLeitura = new double[numPontosLeitura + 1];
	coordYLeitura = new double[numPontosLeitura + 1];
	tempServPontoLeitura = new double[numPontosLeitura + 1];
	inicioJanelaLeitura = new double[numPontosLeitura + 1];
	fimJanelaLeitura = new double[numPontosLeitura + 1];

	tempMaxRotaVLeitura = new double[numVeicLeitura];
	tempMaxEsperaVeiculoLeitura = new double[numVeicLeitura];
	capacidadeDeCadaVeiculoLeitura = new int[numVeicLeitura];
	garagemInicialLeitura = new int[numVeicLeitura];
	garagemFinalLeitura = new int[numVeicLeitura];

	cargaClienteLeitura = new int[numPontosLeitura];
	tempMaxViagemClienteLeitura = new double[numPontosLeitura];
	t = new double*[numPontosLeitura + 1];
	distancias = new double*[numPontosLeitura + 1];
	vetorControleVisita = new bool[numPontosLeitura];
	puts("Criou var da instancia");
	//Le os valores e atribui as variaveis


	for (int i = 0; i <= numPontosLeitura; i++) {
		Instancia >> idPontoLeitura[i];
		Instancia >> coordXLeitura[i];
		Instancia >> coordYLeitura[i];
		Instancia >> tempServPontoLeitura[i];

		Instancia >> infoPontoLeitura[i];

		Instancia >> inicioJanelaLeitura[i];
		Instancia >> fimJanelaLeitura[i];

	}

	for (int i = 1; i <= numPontosLeitura; i++) {
		tempMaxViagemClienteLeitura[i] = tempMaxViagemLeitura;
	}
	for (int i = 1; i <= numPontosLeitura; i++) {
		cargaClienteLeitura[i] = 1 * infoPontoLeitura[i];
		//cout << "Carga(" << cargaCliente[i] << "): "<< endl;
	}

	for (int i = 0; i < numVeicLeitura; i++) {
		tempMaxRotaVLeitura[i] = tempMaxRotaLeitura;
	}

	for (int i = 0; i < numVeicLeitura; i++) {
		capacidadeDeCadaVeiculoLeitura[i] = capacidadeVeiculoLeitura;
	}

	/**  for (int i = 0; i < numVeicLeitura; i++) {
	 garagemInicial[i] = 0;
	 garagemFinal[i] = numPontosLeitura;
	 }
	 **/

	puts("Mat dist");
	//DISTANCIA
	for (int i = 0; i < numPontosLeitura + 1; ++i) {
		distancias[i] = new double[numPontosLeitura + 1];
		t[i] = new double[numPontosLeitura + 1];
	}
	/*
	 double arcoS;
	 int RaioDaTerra = 6378;

	 for (int i = 0; i < numPontos+1; i++) {
	 for (int j = 0; j < numPontos+1; j++) {
	 arcoS = sin(coordX[j]) * sin(coordX[i]) +  cos(coordX[j])*cos(coordX[i])*cos(coordY[i]-coordY[j]);
	 cout << "Arco S(" << j <<"): " << arcoS << " Cos(S)"  << cos(arcoS)<< endl;
	 distancias[i][j] = 0;
	 distancias[i][j] = (cos(arcoS) * RaioDaTerra*1,27);
	 cout << "Distancia(" << i << "," << j <<"): " << distancias[i][j] << endl;
	 }
	 }
	 /*/
	//Distancia Euclidiana
	for (int i = 0; i < numPontosLeitura + 1; i++) {
		for (int j = 0; j < numPontosLeitura + 1; j++) {
			distancias[i][j] = 0;
			distancias[i][j] = sqrt(
					pow((coordXLeitura[j] - coordXLeitura[i]), 2) + pow(
							(coordYLeitura[j] - coordYLeitura[i]), 2)) * 100;
					cout << "Distancia(" << i << "," << j << "): " << distancias[i][j]<< endl;
			t[i][j] = distancias[i][j] ;// velocidadeMedia;
		}

	}
	/**/

	//Cabecalho cabecalho(numVeicLeitura, numPontosLeitura, te);
	// Fecha o arquivo
	puts("Fecha arq");
	//cout << "Distancia " << numPontosLeitura << endl;
	//Instancia.close();

	//Imprime id veiculos
	for (int i = 0; i < numPontosLeitura; i++) {
		vetorControleVisita[i] = true;
	}

	e_Location = new double[numPontosLeitura + 1];
	e_Location = inicioJanelaLeitura;
	l_Location = new double[numPontosLeitura + 1];
	l_Location = fimJanelaLeitura;
	acao_Location= new int[numPontosLeitura + 1];
	acao_Location = infoPontoLeitura;
	s_Location = new double[numPontosLeitura + 1];
	s_Location = tempServPontoLeitura;
	coordX = new double[numPontosLeitura + 1];
	coordX = coordXLeitura;
	coordY = new double[numPontosLeitura + 1];
	coordY = coordYLeitura;
	//cout << "PASSOU AQUI 1" << idPontoLeitura[3] << endl;
	//for (vector<Location>::iterator it; it = vetorLocation.begin(); it != vetorLocation.end();it++){;;
	for (int i = 0; i < numPontosLeitura; i++) {
		//Location(int, double, double, double, double, int, int);
		Location lc(idPontoLeitura[i], coordXLeitura[i], coordYLeitura[i],
				inicioJanelaLeitura[i], fimJanelaLeitura[i],
				tempServPontoLeitura[i], infoPontoLeitura[i]);
		//cout << "PASSOU AQUI" << i << endl;
		/*
		 vetorLocation.at(i).setIdReq(idPontoLeitura[i]);
		 vetorLocation.at(i).setCoordX(coordXLeitura[i]);
		 vetorLocation.at(i).setCoordY(coordYLeitura[i]);
		 vetorLocation.at(i).setE(inicioJanelaLeitura[i]);
		 vetorLocation.at(i).setL(fimJanelaLeitura[i]);
		 vetorLocation.at(i).setS(tempServPontoLeitura[i]);
		 vetorLocation.at(i).setAcao(infoPontoLeitura[i]);**/
		vetorLocation.push_back(lc);

	}
	cout << ">>" << vetorLocation.at(8).getIdReq() << endl;
	cout << ">>" << vetorLocation.at(8).getCoordX() << endl;
	cout << ">>" << vetorLocation.at(8).getCoordY() << endl;
	//cout << "PASSOU AQUI Aqui" << endl;
	Instancia.close();
}

int indexOf(vector<int> elementosDaRota, int elemento) {
	//for (vector<int> ::iterator it = elementosDaRota.begin(); it!= elementosDaRota.end(); it++) {//P e U
	for (int i = 0; i < elementosDaRota.size(); i++) {
		if (elementosDaRota[i] == elemento) {
			return i;
		}
	}
}
